package com.whynot.frame.basic.util;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;
import java.security.SecureRandom;
import java.util.regex.Matcher;
import java.util.regex.Pattern;


/**
 * 
 * @author 1989
 *
 */
public class DES {

  public DES(String str) {
    setKey(str);// 生成密匙
  }

  public DES() {
  }

  public void setKey(String key) {
    PASSWORD_CRYPT_KEY = key;
  }

  private String PASSWORD_CRYPT_KEY = null;

  private final static String DES = "DES/ECB/PKCS5Padding";
  /**
   * 
   * 加密
   * 
   * @param src
   *            数据源
   * 
   * @param key
   *            密钥，长度必须是8的倍数
   * 
   * @return 返回加密后的数据
   * 
   * @throws Exception
   */

  public static byte[] encrypt(byte[] src, byte[] key) throws Exception {

    // DES算法要求有一个可信任的随机数源

    SecureRandom sr = new SecureRandom();

    // 从原始密匙数据创建DESKeySpec对象

    DESKeySpec dks = new DESKeySpec(key);

    // 创建一个密匙工厂，然后用它把DESKeySpec转换成

    // 一个SecretKey对象

    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");

    SecretKey securekey = keyFactory.generateSecret(dks);

    // Cipher对象实际完成加密操作

    Cipher cipher = Cipher.getInstance(DES);

    // 用密匙初始化Cipher对象

    cipher.init(Cipher.ENCRYPT_MODE, securekey, sr);

    // 现在，获取数据并加密

    // 正式执行加密操作

    return cipher.doFinal(src);

  }

  /**
   * 
   * 解密
   * 
   * @param src
   *            数据源
   * 
   * @param key
   *            密钥，长度必须是8的倍数
   * 
   * @return 返回解密后的原始数据
   * 
   * @throws Exception
   */

  public static byte[] decrypt(byte[] src, byte[] key) throws Exception {

    // DES算法要求有一个可信任的随机数源

    SecureRandom sr = new SecureRandom();

    // 从原始密匙数据创建一个DESKeySpec对象

    DESKeySpec dks = new DESKeySpec(key);

    // 创建一个密匙工厂，然后用它把DESKeySpec对象转换成

    // 一个SecretKey对象

    SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");

    SecretKey securekey = keyFactory.generateSecret(dks);

    // Cipher对象实际完成解密操作

    Cipher cipher = Cipher.getInstance(DES);

    // 用密匙初始化Cipher对象

    cipher.init(Cipher.DECRYPT_MODE, securekey, sr);

    // 现在，获取数据并解密

    // 正式执行解密操作

    return cipher.doFinal(src);

  }

  /**
   * 
   * 密码解密
   * 
   * @param data
   * 
   * @return
   * 
   * @throws Exception
   */

  public String decrypt(String data) {

    try {
      return new String(decrypt(hex2byte(data.getBytes()),
      PASSWORD_CRYPT_KEY.getBytes()));
    } catch (Exception e) {
      e.printStackTrace();
    }
    return null;

  }

  /**
   * 
   * 密码加密
   * 
   * @param src
   * 
   * @return
   * 
   * @throws Exception
   */

  public String getEncString(String src) {

    try {

      return byte2hex(encrypt(src.getBytes("UTF-8"), PASSWORD_CRYPT_KEY
          .getBytes("UTF-8"))).toLowerCase();
    } catch (Exception e) {

    }

    return null;

  }

  /**
   * 
   * 二行制转字符串
   * 
   * @param b
   * 
   * @return
   */

  public static String byte2hex(byte[] b) {

    String hs = "";
    String stmp = "";
    for (int n = 0; n < b.length; n++) {
      stmp = (Integer.toHexString(b[n] & 0XFF));
      if (stmp.length() == 1)
        hs = hs + "0" + stmp;
      else
        hs = hs + stmp;
    }
    return hs.toUpperCase();

  }

  public static byte[] hex2byte(byte[] b) {
    if ((b.length % 2) != 0)
      throw new IllegalArgumentException("长度不是偶数");
    byte[] b2 = new byte[b.length / 2];
    for (int n = 0; n < b.length; n += 2) {
      String item = new String(b, n, 2);
      b2[n / 2] = (byte) Integer.parseInt(item, 16);
    }

    return b2;
  }
  
  public static void main(String[] args) {
 
    DES des = new DES();
    des.setKey("08bf46321f863ea1"); //密钥
      String encString = des.getEncString("185110771s0");//加密方法
      System.out.println(encString);
      System.out.println(des.decrypt(encString));//解密方法

   
  }

  /**
   * 加密方法
   * @param key
   * @return
   */
  public static String setEncString(String key){
    DES des = new DES();
    des.setKey("08bf46321f863ea1"); //密钥
    return des.getEncString(key);
  }

  /**
   * 解密方法
   * @param key
   * @return
   */
  public static String setDecrypt(String key){
    DES des = new DES();
    des.setKey("08bf46321f863ea1"); //密钥
    return des.decrypt(key);
  }

  public static boolean isMobile(String str) {   
    Pattern p = null;  
    Matcher m = null;  
    boolean b = false;   
    p = Pattern.compile("^[1][3,4,5,8][0-9]{9}$"); // 验证手机号  
    m = p.matcher(str);  
    b = m.matches();   
    return b;  
}
}